﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Net.Http;
using System.Threading.Tasks;

namespace Zeus.Logger
{
    public class DefaultZLoggerContext : IZLoggerContext
    {
        public Stopwatch TimeWatch { get; set; }

        public string IPAddress { get; set; }

        public string Host { get; set; }

        public string AbsoluteUri { get; set; }

        public string AbsolutePath { get; set; }

        public string HeaderString { get; set; }

        public Dictionary<string, string> Headers { get; set; }

        public Guid GuidRequest { get; set; }

        public string RequestBody { get; set; }

        public int ResponseCode { get; set; }

        public string ResponseBody { get; set; }

        public string Action { get; set; }

        public HttpRequestMessage RequsetHandler { get; set; }

        public async Task BuildContext(HttpRequestMessage httpRequestMessage)
        {
            TimeWatch = new Stopwatch();
            TimeWatch.Start();
            Host = httpRequestMessage.RequestUri.Host;
            IPAddress = httpRequestMessage.GetClientIp();
            AbsoluteUri = httpRequestMessage.RequestUri.AbsoluteUri;
            AbsolutePath = httpRequestMessage.RequestUri.AbsolutePath;

            Headers = new Dictionary<string, string>();
            foreach (var item in httpRequestMessage.Headers)
            {
                var headerValue = HeaderValueToString(item.Value);
                Headers.Add(item.Key, headerValue);
                HeaderString = $"{HeaderString};{item.Key}={headerValue}";
            }
            GuidRequest = httpRequestMessage.GetCorrelationId();
            RequestBody = await httpRequestMessage.Content.ReadAsStringAsync();
            int lastIndexOf = AbsolutePath.LastIndexOf('/');
            Action = lastIndexOf >= 0 ? AbsolutePath.Substring(lastIndexOf) : string.Empty;
            RequsetHandler = httpRequestMessage;
        }

        public async Task BuildContext(HttpResponseMessage httpResponseMessage)
        {
            ResponseCode = (int)httpResponseMessage.StatusCode;
            ResponseBody = string.Empty;
            if (httpResponseMessage.Content != null)
            {
                ResponseBody = await httpResponseMessage.Content.ReadAsStringAsync();
            }
            TimeWatch.Stop();
        }

        private string HeaderValueToString(IEnumerable<string> headers)
        {
            string headerItem = string.Empty;
            foreach (var item in headers)
            {
                headerItem += $"{item},";
            };
            return headerItem.TrimEnd(',');
        }
    }
}
